package ru.urfc.portal.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import ru.urfc.portal.dao.BasePersistence;
import ru.urfc.portal.dao.Paging;
import ru.urfc.portal.dao.RadioDao;
import ru.urfc.portal.dao.SpectrId;
import ru.urfc.portal.model.Client;
import ru.urfc.portal.model.radio.NetLicense;
import ru.urfc.portal.model.radio.NetWithDevicesNumber;
import ru.urfc.portal.model.radio.NetWithLicense;

@Stateless
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class RadioDaoImpl extends BaseDao implements RadioDao {
	@EJB BasePersistence basePersistence;

	@Override
	public List<NetWithDevicesNumber> getNets(Client client, Date issueDate) {
		Class<NetWithLicense> klass = NetWithLicense.class;
		EntityManager entityManager = choseEntityManager(client.getBranch(), klass);
		Query query = entityManager.createQuery(format(
				"SELECT net, COUNT(device) FROM {0} net" +
				" LEFT JOIN net.devices device" +
				" WHERE net.contragent.id = :contragentId" +
				" GROUP BY net",
				klass.getSimpleName()));
		query.setParameter("contragentId", client.getContragentId());
		return wrapToNetWithDevicesNumber(query.getResultList(), client, issueDate);
	}

	private List<NetWithDevicesNumber> wrapToNetWithDevicesNumber(
			List<?> resultList, Client client, Date issueDate) {
		List<NetWithDevicesNumber> result = new ArrayList<NetWithDevicesNumber>();
		for (Object item: resultList) {
			Object[] row = (Object[]) item;
			NetWithLicense net = (NetWithLicense)row[0];
			net.setCurrentLicense(getNetCurrentLicense(new SpectrId(net.getId(), client), issueDate));
			net.setRegion(client.getBranch().getRegion());
			result.add(new NetWithDevicesNumber(net, (Long)row[1]));
		}
		return result;
	}
	
	@Override
	public NetLicense getNetCurrentLicense(SpectrId netId, Date issueDate) {
		return oneOrNull(basePersistence.findWhere(
				netId.getBranch(), NetLicense.class,
				"this.net.id = ?1 and this.issueDate <= ?2",
				"this.expireDate DESC, this.id DESC", Paging.ONE, netId.getId(), issueDate));
	}
	
}
